package edu.upf.opencities.web.action;

import com.opensymphony.xwork2.ActionContext;

import edu.upf.opencities.datamodel.*;
import edu.upf.opencities.web.manager.impl.ManagerImpl;
import edu.upf.opencities.web.utils.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;

/**
 * 
 * @author victor
 */
public class ServiceAction extends BaseAction {

	private static final long serialVersionUID = 1L;
	private static ManagerImpl manager = ManagerImpl.getInstace();
	private List<Service> serviceList;

	private Service currentService;
	private Service newService;
	private String id;
	private String type;
	private Utils util = Utils.getInstance();

	private List<String> searchList;
	private static List<String> licenseList;
	private static List<String> groupList;
	private List<String> rawGroupList;
	private static int[] serviceSize = new int[19];
	private String searchResultsNum;
	private String selectBoxBy;
	private String selectLicense;
	private String selectGroup;
	private String selectBoxArgument;
	private String groupBox;

	//Temp tag list
	private String tempTagList;
	private String isValidable = "false";
	private String isUpdate = "false";

	private String confirmServicePassword;
	
	
	//Others
	private int DESCRIPTION_LENGTH = 72;

	// GET LIST OF SERVICES
	public String getServicesList(){

		searchList = new ArrayList<String>();
		searchList.add("group");
		searchList.add("tag");
		
		session.put("edit","false");
		
		createGroupList();
		searchResultsNum = "0";
		
		String rawGroup = getRequest().getParameter("selectedGroup");
		
		if(rawGroup != null){
			int charIndx = rawGroup.indexOf('(');
			
			if(charIndx!=-1){
				rawGroup = rawGroup.substring(0, charIndx-1);	
				//rawGroup = "Urban Transport";
			}
		}
		
		String selectedGroup = rawGroup;
		
		if(selectedGroup != null){
				serviceList = manager.getServices("group",selectedGroup).getServices();
				serviceList = chopServiceList(serviceList);
				searchResultsNum = "" + serviceList.size();
				int indexGroup = groupList.indexOf(selectedGroup);
				if(indexGroup!=-1){
					serviceSize[indexGroup] = serviceList.size();
				}
		}
		else if (null != session.get("user")) {
			try {
				session.remove("searchType");
			} catch (Exception e) {
			}
			session.put("searchType", "mail");
			String email = ((User) session.get("user")).getEmail();
			serviceList = manager.getServices("mail", email).getServices();
			searchResultsNum = "" + serviceList.size();
		}
			
		return SUCCESS;
	}
	
	public String searchByTag(){
		
		searchList = new ArrayList<String>();
		searchList.add("group");
		searchList.add("tag");
		
		session.put("edit","false");
		
		createGroupList();
		searchResultsNum = "0";
		
		try{
			serviceList = manager.getServices("tag",getSelectBoxArgument()).getServices();
			serviceList = chopServiceList(serviceList);
			searchResultsNum = "" + serviceList.size();
		}catch(NullPointerException e){};
		
		
		return SUCCESS;
	}


	// GET ONE SERVICE
	public String getService() throws IOException {
		setRequest((HttpServletRequest) ActionContext.getContext().get(
				ServletActionContext.HTTP_REQUEST));
		id = getRequest().getParameter("id");
		currentService = manager.getOneService(id);
		tempTagList = "";
		List<String> tagList = currentService.getTags();
		for (String string : tagList) {
			tempTagList += string + ", ";
		}

		if (null != currentService) {
			return SUCCESS;
		}
		return util.returnError("Error while getting the service");
	}

	void createLicenseList() {
		licenseList = new ArrayList<String>();
		licenseList.add("Not Specified");
		licenseList.add("Apache Software License");
		licenseList.add("Apache License, 2.0");
		licenseList.add("Computer Associates Trusted Open Source License 1.1");
		licenseList.add("Creative Commons Attribution");
		licenseList.add("Creative Commons Share-Alike");
		licenseList.add("Creative Commons Non-Commercial (Any)");
		licenseList.add("Creative Commons CCZero");
		licenseList.add("Eclipse Public License");
		licenseList.add("GNU Free Documentation License");
		licenseList.add("GNU General Public License (GPL)");
		licenseList.add("GNU General Public License version 3.0 (GPLv3)");
		licenseList.add("MIT license");
		licenseList.add("Mozilla Public License 1.0 (MPL)");
		licenseList.add("Mozilla Public License 1.1 (MPL)");
		licenseList.add("License Not Specified");
		licenseList.add("Open Data Commons Open Database License (ODbL)");
		licenseList
				.add("Open Data Commons Public Domain Dedication and Licence (PDDL)");
		licenseList.add("W3C License");
	}

	void createGroupList() {
		groupList = new ArrayList<String>();
		rawGroupList = new ArrayList<String>();

		groupList.add("Arts and Recreation");
		groupList.add("Business Enterprise, Economics, and Trade");
		groupList.add("City Budget: Revenues & Expenditures");
		groupList.add("City Portal Web Statistics");
		groupList.add("Construction, Housing, and Public Works");
		groupList.add("Crime and Community Safety");
		groupList.add("Demographics");
		groupList.add("Education");
		groupList.add("Elections");
		groupList.add("Emergency Services");
		groupList.add("Energy and Utilities");
		groupList.add("Environment, Geography and Meteorological");
		groupList.add("Health and Disability");
		groupList.add("Labor Force and Employment Market");
		groupList.add("Law Enforcement, Courts, and Prisons");
		groupList.add("Political");
		groupList.add("Tourism");
		groupList.add("Urban Transport");
		groupList.add("Others");
		
		rawGroupList = new ArrayList<String>();
		rawGroupList.add("Arts and Recreation");
		rawGroupList.add("Business Enterprise, Economics, and Trade");
		rawGroupList.add("City Budget: Revenues & Expenditures");
		rawGroupList.add("City Portal Web Statistics");
		rawGroupList.add("Construction, Housing, and Public Works");
		rawGroupList.add("Crime and Community Safety");
		rawGroupList.add("Demographics");
		rawGroupList.add("Education");
		rawGroupList.add("Elections");
		rawGroupList.add("Emergency Services");
		rawGroupList.add("Energy and Utilities");
		rawGroupList.add("Environment, Geography and Meteorological");
		rawGroupList.add("Health and Disability");
		rawGroupList.add("Labor Force and Employment Market");
		rawGroupList.add("Law Enforcement, Courts, and Prisons");
		rawGroupList.add("Political");
		rawGroupList.add("Tourism");
		rawGroupList.add("Urban Transport");
		rawGroupList.add("Others");

	}

	// START NEW SERVICE
	public String startServiceRegister() {

		createLicenseList();
		createGroupList();
		if (null == session.get("user")){
			return util.returnError("You must be registered to register a new service");
		}
		session.put("edit", "false");
		return SUCCESS;
	}
	
	// EDIT SERVICE
		public String editService() {

			createLicenseList();
			createGroupList();
			session.put("edit","true");

			setRequest((HttpServletRequest) ActionContext.getContext().get(
					ServletActionContext.HTTP_REQUEST));
			
			id = getRequest().getParameter("id");
			setNewService(manager.getOneService(id));
			session.put("editService", getNewService());
			
			//getRequest().setAttribute("edit","true");
			if (getNewService() == null) {
				return util.returnError("Unable to load the service");
			}
			return SUCCESS;

		}


	// FINISH CREATE SERVICE
	public String newService() {
		
		User user = (User) session.get("user");
		getNewService().setEmail(user.getEmail());

		String [] l = tempTagList.split(",");
		for(int i=0; i<l.length ; i++){
			getNewService().getTags().add(l[i]);
		}
		getNewService().setGroup(getSelectGroup());
		getNewService().setLicense(getSelectLicense());
		getRequest().setAttribute("newService", "yes");
		
		currentService = manager.createNewService(getNewService(), user);

		if (currentService != null) {
			return SUCCESS;
		}
		
		return util.returnError("Impossible to create a new service now. Please try later");
	}
	
	// UPDATE SERVICE (SEND TO SERVER)
		public String updateService() {

			User user = (User) session.get("user");
			getNewService().setEmail(user.getEmail());

			String [] l = tempTagList.split(",");
			for(int i=0; i<l.length ; i++){
				getNewService().getTags().add(l[i]);
			}
			getNewService().setGroup(getSelectGroup());
			getNewService().setLicense(getSelectLicense());
			getRequest().setAttribute("newService", "yes");
			
			if(manager.updateService(getNewService(), user)){
				return SUCCESS;
			}
			
			return util.returnError("Impossible to update the service now. Please try later");
			

		}

	// DELETE SERVICE
	public String deleteService() {
		User user = (User) session.get("user");
		Service serv = new Service();
		id = getRequest().getParameter("id");
		serv.setId(id);

		manager.deleteService(serv, user);
		return SUCCESS;
	}

	public void validate() {
		if(isValidable.equalsIgnoreCase("true")){
			createGroupList();
			createLicenseList();
			try {
				if (getNewService().getName().length() == 0) {
					addFieldError("newService.name", "name is required");
				}
				if (getNewService().getPassword().length() == 0) {
					addFieldError("newService.password", "password is required");
				}
				if(!isUpdate.equalsIgnoreCase("true")){
					if(! getNewService().getPassword().equals(confirmServicePassword)){
						addFieldError("newService.password", "passwords do not match");
					}
					isUpdate="false";
				}
				if(tempTagList.length()==0){
					addFieldError("tempTagList","tags are required");
				}
				
				isValidable="false";
			} catch (Exception e) {isValidable="false";isUpdate="false";}
		}
	}
	
	private List<Service> chopServiceList(List<Service> list){
		
		for (Service service : list) {
			String description = service.getDescription();
			if(description.length() > DESCRIPTION_LENGTH){
				description = description.substring(0, DESCRIPTION_LENGTH);
				description = description +"...";
			}
			service.setDescription(description);
		}
		return list;
	}

	// GETTERS AND SETTERS
	public Service getNewService() {
		return newService;
	}

	public void setNewService(Service newService) {
		this.newService = newService;
	}

	public Service getCurrentService() {
		return currentService;
	}

	public void setCurrentService(Service currentService) {
		this.currentService = currentService;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getId() {
		return id;
	}

	public void set(String id) {
		this.id = id;
	}

	public String getSearchResultsNum() {
		return searchResultsNum;
	}

	public void setSearchResultsNum(String searchResultsNum) {
		this.searchResultsNum = searchResultsNum;
	}

	public List<Service> getServiceList() {
		return serviceList;
	}

	public void setServices(Services serviceList) {
		this.serviceList = serviceList.getServices();
	}

	public List<String> getSearchList() {
		return searchList;
	}

	public void setSearchList(List<String> searchList) {
		this.searchList = searchList;
	}

	public List<String> getLicenseList() {
		return licenseList;
	}

	public void setLicenseList(List<String> licenseList) {
		ServiceAction.licenseList = licenseList;
	}

	public List<String> getGroupList() {
		
		groupList = new ArrayList<String>();
		groupList.add("Arts and Recreation ("+ serviceSize[0]+")");
		groupList.add("Business Enterprise, Economics, and Trade ("+ serviceSize[1]+")");
		groupList.add("City Budget: Revenues & Expenditures ("+ serviceSize[2]+")");
		groupList.add("City Portal Web Statistics ("+ serviceSize[3]+")");
		groupList.add("Construction, Housing, and Public Works ("+ serviceSize[4]+")");
		groupList.add("Crime and Community Safety ("+ serviceSize[5]+")");
		groupList.add("Demographics ("+ serviceSize[6]+")");
		groupList.add("Education ("+ serviceSize[7]+")");
		groupList.add("Elections ("+ serviceSize[8]+")");
		groupList.add("Emergency Services ("+ serviceSize[9]+")");
		groupList.add("Energy and Utilities ("+ serviceSize[10]+")");
		groupList.add("Environment, Geography and Meteorological ("+ serviceSize[11]+")");
		groupList.add("Health and Disability ("+ serviceSize[12]+")");
		groupList.add("Labor Force and Employment Market ("+ serviceSize[13]+")");
		groupList.add("Law Enforcement, Courts, and Prisons ("+ serviceSize[14]+")");
		groupList.add("Political ("+ serviceSize[15]+")");
		groupList.add("Tourism ("+ serviceSize[16]+")");
		groupList.add("Urban Transport ("+ serviceSize[17]+")");
		groupList.add("Others ("+ serviceSize[18]+")");
		
		return groupList;
	}

	public void setGroupList(List<String> groupList) {
		
		ServiceAction.groupList = groupList;
	}
	
	public List<String> getRawGroupList() {		
		return rawGroupList;
	}

	public void setRawGroupList(List<String> rawGroupList) {
		this.rawGroupList = rawGroupList;
	}


	public String getSelectBoxBy() {
		return selectBoxBy;
	}

	public void setSelectBoxBy(String selectBoxBy) {
		this.selectBoxBy = selectBoxBy;
	}

	public String getSelectLicense() {
		return selectLicense;
	}

	public void setSelectLicense(String selectLicense) {
		this.selectLicense = selectLicense;
	}

	public String getSelectGroup() {
		return selectGroup;
	}

	public void setSelectGroup(String selectGroup) {
		this.selectGroup = selectGroup;
	}

	public String getSelectBoxArgument() {
		return selectBoxArgument;
	}

	public void setSelectBoxArgument(String selectBoxArgument) {
		this.selectBoxArgument = selectBoxArgument;
	}

	public String getTempTagList() {
		return tempTagList;
	}

	public void setTempTagList(String tempTagList) {
		this.tempTagList = tempTagList;
	}

	public String getGroupBox() {
		return groupBox;
	}

	public void setGroupBox(String groupBox) {
		this.groupBox = groupBox;
	}


	public String getConfirmServicePassword() {
		return confirmServicePassword;
	}

	public void setConfirmServicePassword(String confirmServicePassword) {
		this.confirmServicePassword = confirmServicePassword;
	}
	public String getIsValidable(){
		return isValidable;
	}
	public void setIsValidable(String v){
		isValidable = v;
	}
	public String getIsUpdate(){
		return isUpdate;
	}
	public void setIsUpdate(String v){
		isUpdate = v;
	}
}
